#include     <stdio.h>      
#include     <stdlib.h>     
#include     <unistd.h>     
#include     <fcntl.h>      
#include     <termios.h>    
#include     <errno.h>      

#include <time.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <sys/types.h>

#include <dlfcn.h>

void* slib=0;

int (*OpenComm)();						
int (*ResetSelfCheck)();				
int (*ResetAndSetPin)();				
int (*GetDeviceNo)(char*);				
int (*GetVer)(char*);					
int (*SetEncryptMode)(int);			
int (*SetPinLen)(int);					
int (*LoadMasterKey)(int, char*);		
int (*LoadWorkKey)(int, int, char*);	
int (*ActivWorkPin)(int, int);			
int (*PinEnableMode)(char*);			
int (*CheckPressedBuf)(char*,long);	
int (*PinReadPin)(char*);				
int (*Encrypt)(char*, char*);			
int (*UnEncrypt)(char*, char*);		
int (*CalcMacData)(char*, char*);		
int (*CloseComm)();					
void (*geterror)(char*);				

int (*SetSamSlot)(int);				
int (*SamPowerOn)(char*,int *);		
int (*SamApdu)(char*,char*,int *);		
int (*EnableGetdata)();
int (*KeyboardClose)();

const char* hError;

#define InfoLen  128
char ErrorInfo[InfoLen] = {0};				

int MainKeyDownFlag = 0;		

int main(int argc, char ** argv)
{
    int iRetu;
    int nread;
    char buff[512];
    int iLen;
    
    char bBuff[10] = {0};		
    int bExit; 					
       
    int ch;
    char cmd[30];
    int i=0;
    int iPos;
    int TmpEncryptMode = 0;
    
    char pWorkKeyMw[33];
    char pMaserKeyMw[33];
    char pEncryptMw[17];
    char pEncryptMwLeft[9];
    char pEncryptMwRight[9];
    
    unsigned char cInput[17];			
	unsigned char cOutput[17];			
	
	unsigned char cMacInput[17];		
	unsigned char cPinLenMax[2];
    
    char cCard[20] = {0};
    
    char tmp[33];
    char tmp1[17];
    char tmp2[17];
    
    unsigned char pPinBlock[9];
    
    clock_t start, finish,internalTime;
    
    struct termios stored_settings;
    struct termios new_settings;
    tcgetattr (0, &stored_settings);
    new_settings = stored_settings;
    new_settings.c_lflag &= (~ICANON);
    new_settings.c_cc[VTIME] = 0;
    new_settings.c_cc[VMIN] = 1;
    tcsetattr (0, TCSANOW, &new_settings);    
    
    int iMasterKeyID;
    int iWorkKeyID;
    
    char pMasterKeyID[3];
    char pWorkKeyID[3];
    
    char pMasterKey[33];
    char pWorkKey[33];
				
    while(1)
    {  
        printf("\n");
        printf("*-----------------------------------------------------------*\n");
        printf("*                                                           *\n");
        printf("*                    KMY                                    *\n");
        printf("*           KMY 350 pinopad Test(v1.0)                      *\n");        
        printf("*                                                           *\n");
        printf("*    1 : Open Comm                                          *\n");
        printf("*    2 : Reset                      3 : Reset(Clear key)    *\n");
        printf("*    4 : GetVer                     5 : Getid               *\n");
        printf("*    A : SetDESMode                 B : SetTDESMode         *\n");
        printf("*    C : SetPinLen(Auto len=6)                              *\n");
        printf("*    6 : LoadMasterKey                                      *\n");
        printf("*    7 : LoadWorkKey                                        *\n");
        printf("*    8 : ActiveKey                                          *\n");
        printf("*    D : PinBlock                                           *\n");
        printf("*    E : DataEnc                    F : DataDec             *\n");
        printf("*    G : MAC                        K : GetData             *\n");
        printf("*    9 : Close Comm                                         *\n");
        printf("*    0 : Exit Program                                       *\n");
        printf("*-----------------------------------------------------------*\n");
        printf("     Please Select(0,1,2,3,4,5,a,b,c,6,7,8,d,e,f,g,9):");
        ch = getchar();
        switch(ch)
        {
            case '0':
            	printf("\n\n");
                exit(1);
                break;
            case '1':
				slib=dlopen("./kmy350.so",RTLD_LAZY);
				hError=dlerror();
				if (hError)
				{
					printf("dlopen Error!\n");
					return 1;
				}    
				geterror=dlsym(slib,"geterror");
				if (hError)
				{
					printf("dlsym Error!\n");
					return 1;
				}
	            	
				OpenComm=dlsym(slib,"OpenComm");
				if (hError)
				{
					printf("dlsym Error!\n");
					return 1;
				}
				iRetu = OpenComm();
				if (iRetu) 
				{
					geterror(ErrorInfo);
					printf("\n %s \n ",ErrorInfo);
				}
				else
					printf("\nOpen Port succese\n");
				break;
				
            case '2':		
            	ResetSelfCheck=dlsym(slib,"ResetSelfCheck");
            	if (hError)
				{
					printf("dlsym Error!\n");
					return 1;
				}
				iRetu = ResetSelfCheck();
				if (iRetu) 
				{
					geterror(ErrorInfo);
					printf("\n %s \n ",ErrorInfo);
				}
				else
					printf("\nReset OK��\n");	
				break;
				
            case '3':		
            	ResetAndSetPin=dlsym(slib,"ResetAndSetPin");
            	if (hError)
				{
					printf("dlsym Error!\n");
					return 1;
				}
				iRetu = ResetAndSetPin();
				if (iRetu) 
				{
					geterror(ErrorInfo);
					printf("\n %s \n ",ErrorInfo);
				}
				else
					printf("\nReset OK(Clear Key)��\n");	
				break;
				
            case '4':		
            	GetVer=dlsym(slib,"GetVer");
            	if (hError)
				{
					printf("dlsym Error!\n");
					return 1;
				}
				iRetu = GetVer(buff); 
				if (iRetu) 
				{
					geterror(ErrorInfo);
					printf("\n %s \n ",ErrorInfo);
				}
				else
				{
					printf("\nRev=%s\n",buff);
        			printf("\nGet Ver OK��\n");	
				}
				break;
                       
            case '5':		
            	GetDeviceNo=dlsym(slib,"GetDeviceNo");
            	if (hError)
				{
					printf("dlsym Error!\n");
					return 1;
				}
				iRetu = GetDeviceNo(buff);
				if (iRetu) 
				{
					geterror(ErrorInfo);
					printf("\n %s \n ",ErrorInfo);
				}
				else
				{
					printf("\nRev=%s\n",buff);
        			printf("\nGet ID OK��\n");			
				}
				break;
				
            case 'A':	
            case 'a':		
            	SetEncryptMode=dlsym(slib,"SetEncryptMode");
            	if (hError)
				{
					printf("dlsym Error!\n");
					return 1;
				}
            	iRetu = SetEncryptMode(0);		
            	if (iRetu) 
				{
					geterror(ErrorInfo);
					printf("\n %s \n ",ErrorInfo);
				}
				else
        			printf("\nSetEncMode��DES	OK��\n");		
        		TmpEncryptMode = 0;	
                break;
                
            case 'B':		
            case 'b':
            	SetEncryptMode=dlsym(slib,"SetEncryptMode");
            	if (hError)
				{
					printf("dlsym Error!\n");
					return 1;
				}
            	iRetu = SetEncryptMode(1);		
            	if (iRetu) 
				{
					geterror(ErrorInfo);
					printf("\n %s \n ",ErrorInfo);
				}
				else
        			printf("\nSetEncMode��3DES	OK��\n");	
        		TmpEncryptMode = 1;			
                break;
            	
            case 'C':		
            case 'c':
            	SetPinLen=dlsym(slib,"SetPinLen");
            	if (hError)
				{
					printf("dlsym Error!\n");
					return 1;
				}
            	memset(cPinLenMax,'\0',2);
	            printf("\nPlease Input Pin Len:");
	            fgets(cPinLenMax,2,stdin);     
	                      	
	            iRetu = SetPinLen(atoi(cPinLenMax));
	            if (iRetu) 
				{
					geterror(ErrorInfo);
					printf("\n %s \n ",ErrorInfo);
					break;
				}
				else
            		printf("\nSet Pin Len OK��\n");
            	break;				
                
            case '6':		
            	LoadMasterKey=dlsym(slib,"LoadMasterKey");
            	if (hError)
				{
					printf("dlsym Error!\n");
					return 1;
				}
        		memset(pMasterKeyID,'\0',3);
	            printf("\nPlease Mkey ID(00,01...15):");
	            fgets(pMasterKeyID,3,stdin);  
	            
	            iMasterKeyID = atoi(pMasterKeyID);   	
	                      	
            	if (TmpEncryptMode==0)	
            	{
	            	memset(pMasterKey,'\0',33);
	            	printf("\nPlease Input Mkey Data��8ByteHEX��:");
	            	fgets(pMasterKey,17,stdin);               		
            		if (MainKeyDownFlag==0)	
            		{
            			printf("\nLoad Mkey  MkeyID=%d, Mkey=%s\n",iMasterKeyID,pMasterKey);
            			if (LoadMasterKey(iMasterKeyID,pMasterKey) == 1)
            			{
		            		geterror(ErrorInfo);
							printf("\n %s \n ",ErrorInfo);
		            	}
            			else
        					printf("\nLoad Mkey  mode�� DES OK��\n");	          
            		}
            		else						
            		{
            		
            		}
            	}
            	else											
            	{
	            	memset(pMasterKey,'\0',33);
	            	printf("\n Please Input Mkey��16byteHEX��:");
	            	fgets(pMasterKey,33,stdin);               		
            		if (MainKeyDownFlag==0)		
            		{
            			printf("\nLoad MKey  MkeyID=%d, Mkey=%s\n",iMasterKeyID,pMasterKey);
            			if (LoadMasterKey(iMasterKeyID,pMasterKey)==1)
            			{
		            		geterror(ErrorInfo);
							printf("\n %s \n ",ErrorInfo);
		            	}
            			else
        					printf("\nLoad Mkey  Mode�� 3DES OK��\n");	          
            		}
            		else					
            		{		
            			
            		}        		
            	}            		
            	break;
            	
            case '7':		
            	LoadWorkKey=dlsym(slib,"LoadWorkKey");
            	if (hError)
				{
					printf("dlsym Error!\n");
					return 1;
				}
				
        		memset(pMasterKeyID,'\0',3);
	            printf("\nPlease Input MkeyID(00,01...15):");
	            fgets(pMasterKeyID,3,stdin);  
	            
	            iMasterKeyID = atoi(pMasterKeyID);   	
	            
	            memset(pWorkKeyID,'\0',3);
	            printf("\nPlease Input WkeyID(00,01...15):");
	            fgets(pWorkKeyID,3,stdin);  
	            
	            iWorkKeyID = atoi(pWorkKeyID);   		
            	
            	if (TmpEncryptMode == 0)				
            	{
	            	memset(pWorkKey,'\0',33);
	            	printf("\nPlease Input Wkey��8byteHEX��:");
	            	fgets(pWorkKey,17,stdin);               		

            		
            		printf("\nLoad Wkey  MkeyID=%d, WkeyID=%d,Wkey=%s\n",iMasterKeyID,iWorkKeyID,pWorkKey);
            		

            		if (LoadWorkKey(iMasterKeyID,iWorkKeyID,pWorkKey) == 1)
            		{
	            		geterror(ErrorInfo);
						printf("\n %s \n ",ErrorInfo);
	            		break;
	            	}
	            	else
	        			printf("\nLoad Wkey DES OK��\n");	            		
            	}
            	else										
            	{
            		
	            	memset(pWorkKeyMw,'\0',33);
	            	printf("\nPlease Input Wkey��16byteHEX��:");
	            	fgets(pWorkKeyMw,33,stdin);
		
            		printf("\nLoad Wkey  MkeyID=%d, WkeyID=%d,Wkey=%s\n",iMasterKeyID,iWorkKeyID,pWorkKeyMw);
            		
            		if (LoadWorkKey(iMasterKeyID,iWorkKeyID,pWorkKeyMw) == 1)
	            	{
	            		geterror(ErrorInfo);
						printf("\n %s \n ",ErrorInfo);
	            		break;
	            	}
	            	else
	        			printf("\nLoad Wkey 3DES OK��\n");	            		      		
            	}                  	         		
            	break;                	
                
            case '8':			
            	ActivWorkPin=dlsym(slib,"ActivWorkPin");
            	if (hError)
				{
					printf("dlsym Error!\n");
					return 1;
				}
				
        		memset(pMasterKeyID,'\0',3);
	            printf("\nPlease Input Active MkeyID(00,01...15):");
	            fgets(pMasterKeyID,3,stdin);  
	            
	            iMasterKeyID = atoi(pMasterKeyID);   	
	            
	            memset(pWorkKeyID,'\0',3);
	            printf("\nPlease Input Active WkeyID(00,01...15):");
	            fgets(pWorkKeyID,3,stdin);  
	            
	            iWorkKeyID = atoi(pWorkKeyID);   	
	                        	
            	//iRetu = ActivWorkPin(iWorkKeyID, iMasterKeyID);
		iRetu = ActivWorkPin(iMasterKeyID, iWorkKeyID);
            	if (iRetu) 
				{
					geterror(ErrorInfo);
					printf("\n %s \n ",ErrorInfo);
				}
				else
				{
        			printf("\nActive Wkey OK��\n");			
        		}
            	break;       
            	
            case 'D':
            case 'd':			
            	PinEnableMode=dlsym(slib,"PinEnableMode");
            	if (hError)
				{
					printf("dlsym Error!\n");
					return 1;
				}
				CheckPressedBuf=dlsym(slib,"CheckPressedBuf");
            	if (hError)
				{
					printf("dlsym Error!\n");
					return 1;
				}
				PinReadPin=dlsym(slib,"PinReadPin");
            	if (hError)
				{
					printf("dlsym Error!\n");
					return 1;
				}
				
				memset(pPinBlock,'\0',9);
	            memset(cCard,'\0',20);
	            printf("\nPlease Input Car��>13byteASC��:");
	            fgets(cCard,20,stdin);               		

            	printf("Enc Car=%s\n",cCard);
            	if (PinEnableMode(cCard) == 1)
            	{
            		geterror(ErrorInfo);
					printf("\n %s \n ",ErrorInfo);
            	}
            	else
        			printf("\nPinBlock Begin��Please Input Pw��\n");	    
        		
        		bExit = 0;
        		
        		int lTimeout = 30000;				
        		clock_t start, finish,internalTime;
				internalTime=lTimeout*1000;
				start=clock();
				
				while (!bExit)
				{
					iRetu = CheckPressedBuf(bBuff, 10);
					finish=clock();
					if((finish-start)>internalTime)
					{
						printf("Input Timeout\n");
						break;
					}
					
					if (iRetu == 1) continue;

					switch(bBuff[0]) 
					{
						case 0x2A:		
							printf("%02X\n",bBuff[0]);
							bBuff[0] = 0x00;
							break;
							
						case 0x0D:		
							PinReadPin(pPinBlock);
							for (i = 0; i< 8; i++)
								printf("0x%02X ",pPinBlock[i]);
								
							bExit = 1;
							break;
							
						case 0x08:		
							break;
							
						case 0x1B:		
							bExit = 1;
							printf("\nExit ANSI9.8\n");
							break;
							
						default:
							bExit = 0;
							break;
					}
					if (bExit == 1) break;
				}
            	break;
            	
            case 'E':
            case 'e':		
            	Encrypt=dlsym(slib,"Encrypt");
            	if (hError)
				{
					printf("dlsym Error!\n");
					return 1;
				}
				
	            memset(cInput,'\0',17);
	            memset(cOutput,'\0',17);
	            printf("\nPlease Input Enc Data��8byteHEX��:");
	            fgets(cInput,17,stdin);               		
            	printf("\nEnc Data=%s\n",cInput);
            	if (Encrypt(cInput,cOutput) == 1)
            	{
            		geterror(ErrorInfo);
					printf("\n %s \n ",ErrorInfo);
            	}
            	else
            	{
            		printf("\nEnc OK��\n");	
            		for (i = 0; i< 8; i++)
						printf("0x%02X ",cOutput[i]);
        		}
            	break;
            	
            case 'F':
            case 'f':			
            	UnEncrypt=dlsym(slib,"UnEncrypt");
            	if (hError)
				{
					printf("dlsym Error!\n");
					return 1;
				}
				
	            memset(cInput,'\0',17);
	            memset(cOutput,'\0',17);
	            printf("\nPlease Input DecData��8byteHEX��:");
	            fgets(cInput,17,stdin);               		
            	printf("\nDec Data=%s\n",cInput);
            	if (UnEncrypt(cInput,cOutput) == 1)
            	{
            		geterror(ErrorInfo);
					printf("\n %s \n ",ErrorInfo);
            	}
            	else
            	{
            		printf("\nDec OK��\n");	
            		for (i = 0; i< 8; i++)
						printf("0x%02X ",cOutput[i]);
        		}
            	break;
            	
            case 'G':
            case 'g':				
            	CalcMacData=dlsym(slib,"CalcMacData");
            	if (hError)
				{
					printf("dlsym Error!\n");
					return 1;
				}
				
	            memset(cMacInput,'\0',17);
	            memset(cOutput,'\0',17);
	            printf("\nPlease Input Mac Data��HEX��:");
	            fgets(cMacInput,17,stdin);               		
            	printf("\nMac Data=%s\n",cInput);
            	if (CalcMacData(cMacInput,cOutput) == 1)
            	{
            		geterror(ErrorInfo);
					printf("\n %s \n ",ErrorInfo);
            	}
            	else
            	{
            		printf("\nMAC OK��\n");	
            		for (i = 0; i< 8; i++)
						printf("0x%02X ",cOutput[i]);
        		}
            	break;				
                
            case '9':		
            	CloseComm=dlsym(slib,"CloseComm");
            	if (hError)
				{
					printf("dlsym Error!\n");
					return 1;
				}
            	iRetu = CloseComm();
				if (iRetu) 
				{
					geterror(ErrorInfo);
					printf("\n %s \n ",ErrorInfo);
				}
				else
				{
					printf("\nClose Port OK\n");
				}
				//dlclose(slib);	
                break;
            case 'h':		
            case 'H':		
            	SetSamSlot=dlsym(slib,"SetSamSlot");
            	if (hError)
				{
					printf("dlsym Error!\n");
					return 1;
				}
            	iRetu = SetSamSlot(1);
				if (iRetu) 
				{
					geterror(ErrorInfo);
					printf("\n %s \n ",ErrorInfo);
				}
				else
				{
					printf("\nClose Port OK\n");
				}
				//dlclose(slib);	
                break;                
            case 'i':		
            case 'I':		
            	SamPowerOn=dlsym(slib,"SamPowerOn");
            	if (hError)
				{
					printf("dlsym Error!\n");
					return 1;
				}
            	iRetu = SamPowerOn(cOutput,&iLen);
				if (iRetu) 
				{
					geterror(ErrorInfo);
					printf("\n %s \n ",ErrorInfo);
				}
				else
				{
					printf("\r\natr= ");
            		for (i = 0; i< iLen; i++)
						printf("0x%02X ",cOutput[i]);
					printf("\nClose Port OK\n");
				}
				//dlclose(slib);	
                break;                         
           case 'j':		
            case 'J':		
            	SamApdu=dlsym(slib,"SamApdu");
            	if (hError)
				{
					printf("dlsym Error!\n");
					return 1;
				}
            	iRetu = SamApdu("00A40000023F00",cOutput,&iLen);
				if (iRetu) 
				{
					geterror(ErrorInfo);
					printf("\n %s \n ",ErrorInfo);
				}
				else
				{
					printf("\r\natr= ");
            		for (i = 0; i< iLen; i++)
						printf("0x%02X ",cOutput[i]);
					printf("\nClose Port OK\n");
				}
				//dlclose(slib);	
                break;    
	  case 'K':
	  case 'k':
		KeyboardClose=dlsym(slib,"KeyboardClose");
		if(hError){
			printf("dlsym Error!\n");
			return 1;
        }
	  	EnableGetdata=dlsym(slib,"EnableGetdata");
            	if (hError)
				{
					printf("dlsym Error!\n");
					return 1;
				}
				CheckPressedBuf=dlsym(slib,"CheckPressedBuf");
            	if (hError)
				{
					printf("dlsym Error!\n");
					return 1;
				}
				

                  if (EnableGetdata() == 1)
            	{
            		geterror(ErrorInfo);
					printf("\n %s \n ",ErrorInfo);
            	}
            	else
        			printf("\nPlease Input\n");
        		bExit = 0;
        		
        		int lTimeout1 = 30000;				
        		clock_t start1, finish1,internalTime1;
				internalTime1=lTimeout1*1000;
				start1=clock();
				
				while (!bExit)
				{
					iRetu = CheckPressedBuf(bBuff, 10);
					finish1=clock();
					if((finish1-start1)>internalTime1)
					{
						printf("Input Timeout\n");
						break;
					}
					
					if (iRetu == 1) continue;

					switch(bBuff[0]) 
					{
						case 0x30:
						case 0x31:
						case 0x32:
						case 0x33:
						case 0x34:
						case 0x35:
						case 0x36:
						case 0x37:
						case 0x38:
						case 0x39:
							printf("%02X\n",bBuff[0]);
							bBuff[0] = 0x00;
							break;
						case 0x2E:
							printf(".\n");
							bBuff[0] = 0x00;
							break;
						case 0x2A:
							printf("*\n");
							bBuff[0] = 0x00;
							break;
						case 0x23:
							printf("#\n");
							bBuff[0] = 0x00;
							break;
							
						case 0x0D:								
							bExit = 1;
							break;
							
						case 0x08:		
							break;
							
						case 0x1B:		
							bExit = 1;
							break;
							
						default:
							bExit = 0;
							break;
					}
					if (bExit == 1) break;
				}
				KeyboardClose();
				printf("Close KeyBoard imput OK!\n");
			  	break;
         default:
                break; 
        }
    }//while(1);
    
    tcsetattr (0, TCSANOW, &stored_settings);
}

